#version 430 core

layout(local_size_x=256) in;

layout(binding=0) coherent buffer sparseMatrixBuffer
{
	float sparseMatrix[];
};

layout(binding=1) coherent buffer inVectorBuffer
{
	float inVector[];
};

layout(binding=2) coherent buffer outVectorBuffer
{
	float outVector[];
};

layout(binding=3) coherent buffer nodeNeighborhoodBuffer
{
	int nodeNeighborhood[];
};

uniform uint numRows;

void main(void)
{
	uint rowID = gl_GlobalInvocationID.x;
	if (rowID < numRows)
	{
		uint index = rowID * 9;
		float result = 0.0;

		for (uint i=0; i<9; i++)
		{
			int neighbor = nodeNeighborhood[index];
			if (neighbor >= 0)
			{
				result += sparseMatrix[index] * inVector[neighbor];
			}
			index++;
		}

		outVector[rowID] = result;
	}
}